package com.ruoyi.notice.service.impl;

import com.ruoyi.notice.mapper.OrderServiceMapper;
import com.ruoyi.notice.mapper.TotalAmountMapper;
import com.ruoyi.notice.mapper.WithdrawalMapper;
import com.ruoyi.notice.service.FyMoneyLogService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

/**
 * @author 23118
 * @version 1.0
 * @description: TODO
 * @date 2025/5/17 15:42
 */
@Service
public class FyMoneyLogServiceImpl implements FyMoneyLogService {

    @Autowired
    private OrderServiceMapper orderServiceMapper;
    @Autowired
    private WithdrawalMapper withdrawalMapper;
    @Autowired
    private TotalAmountMapper totalAmountMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 获取用户的资金变动日志
     * @return
     */
    @Override
    public List<Map> getFyMoneyLog(Long userId) {
        //最终结果集
        List<Map> result = new ArrayList<>();
        //获取所用的订单信息
        List<Map> orders = orderServiceMapper.getOrdersByMid(userId);
        //遍历订单信息
        for (Map order : orders) {
//            System.out.println(fyMoneyLog);
            String name = orderServiceMapper.getServiceNameById(order.get("service_id"));
//            System.out.println(fyMoneyLog);
            //整合结果集
            Map map = new HashMap<>();
            //设置订单id
            map.put("id",order.get("id"));
            //设置订单服务名称
            map.put("name",name);
            //设置下单时间
            //将下单时间转换为yyyy-MM-dd HH:mm:ss格式
            Object orderTimeObj = order.get("order_time");
            String formattedDate = null;

            if (orderTimeObj instanceof LocalDateTime) {
                // 将 LocalDateTime 转换为 Date
                LocalDateTime localDateTime = (LocalDateTime) orderTimeObj;
                Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

                // 格式化
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                formattedDate = sdf.format(date);
                map.put("time",formattedDate);
            }
            //设置订单金额
            map.put("amount",order.get("order_price"));
            //设置订单标识
            map.put("type","income");
            result.add(map);
        }
        //获取所有的提现信息
        List<Map> withdraws = withdrawalMapper.getWithdrawalsByMid(userId);
        //遍历提现信息
        for (Map withdraw : withdraws) {
//            System.out.println(withdraw);
            //整合结果集
            Map map = new HashMap<>();
            //设置提现id
            map.put("id",withdraw.get("id"));
            //设置提现服务名称
            map.put("name","提现");
            //设置提现时间
            map.put("time",withdraw.get("withdrawal_record"));
            //设置提现金额
            map.put("amount",withdraw.get("cash_withdrawal"));
            //设置提现标识
            map.put("type","expense");
            result.add(map);
        }
        //按照时间倒序排序
        result.sort((o1, o2) -> {
            // 比较时间字段
            String time1 = (String) o1.get("time");
            String time2 = (String) o2.get("time");
            return time2.compareTo(time1);
        });
        return result;
    }

    @Override
    public double getBalance(Long userId) {
        Double balance = totalAmountMapper.getBalance(userId);
        return balance != null ? balance : 0;
    }

    @Override
    public double getTotalIncome(Long userId) {
        Double totalIncome = orderServiceMapper.getTotalIncome(userId);
        return totalIncome != null ? totalIncome : 0;
    }

    @Override
    public double getTotalWithdrawal(Long userId) {
        Double totalWithdrawal = withdrawalMapper.getTotalWithdrawal(userId);
        return totalWithdrawal!= null? totalWithdrawal : 0;
    }

    @Override
    public List<Map> getWithdrawal(Long userId) {
        List<Map> result = new ArrayList<>();
        List<Map> withdrawal = withdrawalMapper.getWithdrawal(userId);
        for (Map map : withdrawal) {
//            System.out.println(map);
            Map map1 = new HashMap();
            map1.put("id",map.get("id"));
            map1.put("date",map.get("withdrawal_record"));
            map1.put("status",map.get("status"));
            map1.put("amount",map.get("cash_withdrawal"));
            result.add(map1);
        }
        return result;
    }

    @Override
    @Transactional
    public int addWithdrawal(Map map) {
        //修改用户的余额
        int mid = (Integer) map.get("merchant_id");
        //先根据商户id查询用户的余额
        long merchantId = mid;
        double balance = totalAmountMapper.getBalance(merchantId);
        // 检查 cash_withdrawal 的类型并转换为 double
        Object cashWithdrawalObj = map.get("cash_withdrawal");
        double cash_withdrawal;
        if (cashWithdrawalObj instanceof String) {
            cash_withdrawal = Double.parseDouble((String) cashWithdrawalObj);
        } else if (cashWithdrawalObj instanceof Number) {
            cash_withdrawal = ((Number) cashWithdrawalObj).doubleValue();
        } else {
            throw new IllegalArgumentException("不支持的类型: " + cashWithdrawalObj.getClass());
        }
        // 检查余额是否足够
        if (balance < cash_withdrawal) {
            return 0;
        }
        double total = balance - cash_withdrawal;
        int j = totalAmountMapper.updateBalance(mid,total);
        if (j == 0) {
            return 0;
        }

//        System.out.println(map);
        //设置提现时间
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String formattedDate = sdf.format(date);
        map.put("withdrawal_record",formattedDate);
        //设置提现状态
        map.put("status",0);
        map.put("current_balance",total);
        int i = withdrawalMapper.addWithdrawal(map);
        //借用mq实现定时任务
        //向mq发送该消息
        rabbitTemplate.convertAndSend("car_notice_exchange","withdrawal",map);
        return i;
    }
}
